<template>
  <div class="dh-field">
    <div class="van-hairline--bottom">
      <van-field v-model="resultLabel" v-bind="$attrs" readonly :is-link="$attrs.disabled === undefined || $attrs.disabled === false" input-align="right" @click="showPopu($attrs.disabled as any)" error-message-align="right" class="dh-cell" />
      <van-popup v-model:show="data.show" position="bottom">
        <van-field v-model="data.searchVal" class="search" :placeholder="searchPh" @update:model-value="search" v-if="isSearch" input-align="left" />
        <van-picker v-bind="$attrs" :columns="data.columnsData" :columns-field-names="columnsFieldNames" show-toolbar v-model="data.selectedValues" @cancel="cancel" @confirm="onConfirm" @change="change" />
      </van-popup>
    </div>
  </div>
</template>

<script setup lang="ts">
//更新发送model
const emit = defineEmits(['update:modelValue', 'confirm', 'change', 'cancel', 'click'])

const props = defineProps({
  modelValue: {
    type: [String, Number],
    default: ''
  },
  columns: {
    type: Array<object | number | string>,
    default: function () {
      return []
    }
  },

  columnsFieldNames: {
    type: Object,
    default: function () {
      return { text: 'text', value: 'value' }
    }
  },
  isSearch: {
    type: Boolean,
    default: false
  },

  searchPh: {
    type: String,
    default: '输入搜索信息'
  }
})
interface Config {
  show: boolean
  searchVal: string
  resultValue: string | number
  columnsData: Array<any>
  default_index: number // 默认选中项索引
  selectedValues: Array<any>
}
const data: Config = reactive({
  show: false,
  searchVal: '',
  resultValue: props.modelValue,
  columnsData: [],
  default_index: 0, // 默认选中项索引
  selectedValues: []
})

//回显label
const resultLabel = computed(() => {
  const res = props.columns.filter(item => {
    const val = item[props['columnsFieldNames'].value]
    return val === data.resultValue
  })
  let label = ''
  if (res.length) {
    label = res[0][props['columnsFieldNames'].text]
  }

  return label || props.modelValue
})

//因为props的数据是只读，不能用于绑定model，所以需要重新定义赋值
watch(
  () => props.modelValue,
  newVal => {
    data.resultValue = newVal
    data.selectedValues = [newVal]
  },
  {
    immediate: true,
    deep: true
  }
)

//搜索
const search = (val: string) => {
  if (val) {
    data.columnsData = props.columns.filter(item => {
      const res = item[props['columnsFieldNames'].text]
      return res.indexOf(val) > -1
    })
  } else {
    data.columnsData = JSON.parse(JSON.stringify(props.columns))
  }
}
//操作
const onConfirm = (value: any) => {
  let val = ''
  if (value) {
    val = value.selectedValues[0]
  }
  data.resultValue = val
  data.show = !data.show
  emit('confirm', value, val)
  emit('update:modelValue', val)
}
const change = (value: any) => {
  let val = ''
  if (value) {
    val = value.selectedValues[0]
  }
  emit('change', value, val)
}
const cancel = () => {
  data.show = !data.show
  emit('cancel')
}
const showPopu = (disabled: boolean | undefined = false) => {
  data.columnsData = JSON.parse(JSON.stringify(props.columns))
  data.resultValue = props.modelValue
  if (disabled !== undefined && disabled !== false) {
    return false
  } else {
    data.show = !data.show
  }
}

watch(
  () => data.resultValue,
  () => {
    data.searchVal = ''
    data.columnsData = JSON.parse(JSON.stringify(props.columns))
  },
  {
    immediate: true,
    deep: true
  }
)

//这里需要暴露出去不然父组件调用不到这个方法
defineExpose({
  showPopu
})
</script>

<style lang="scss" scoped>
.dh-field {
  padding: 0 16px;
  background: #fff;
  .dh-cell.van-cell {
    padding: 10px 0;
  }
  .dh-cell.van-cell--required::before {
    left: -8px;
  }
  .van-popup {
    border-radius: 20px 20px 0 0;
  }
}
.search {
  :deep(.van-field__value) {
    background: #f7f7f7;
    padding: 2px;
  }
}
</style>
